home *** CD-ROM | disk | FTP | other *** search
/ Collection of Tools & Utilities / Collection of Tools and Utilities.iso / dirut / free2.zip / FREE.C < prev    next >
Text File  |  1986-12-17  |  5KB  |  137 lines

  1. /*  FREE command - Dec 1986 - Rev. 2 - for DeSmet C
  2. Vincent Bly  Nanosoft  PO Box 409  Ft. Belvoir, VA  22060
  3.  
  4. ***  Returns free disk space or free RAM memory  ***
  5. *** Sets errorlevel if less than spec bytes free ***
  6.  
  7. Call from DOS or batch file:
  8. FREE [N[:]] [MINREQ] [+]
  9.  
  10. Examples:
  11. FREE        (displays free space on current drive)
  12. FREE A        (displays free space on drive A)
  13. FREE C:     (displays free space on drive C)
  14. FREE B: +    (displays free space on drive B & shows disk data)
  15. FREE M        (displays free RAM memory)
  16. FREE 50000    (displays free space on current drive & sets errorlevel
  17.          to 1 if less than 50,000 bytes are available )
  18. FREE M 256000    (displays free RAM & sets errorlevel 1 if less than 256K free)
  19. */
  20.  
  21. #define DOS_FUNC(n)  _rax = ((n) << 8), _doint(0x21)
  22.  
  23. extern long atol();
  24. extern unsigned _rax, _rbx, _rcx, _rdx, _rds, _res, _carryf;
  25. long free_bytes, minval = 0L;    /* 0 => default minimum required memory */
  26. unsigned topram, pspseg;    /* used in calculating free RAM memory */
  27. int verbose = 0;        /* extra information flag, set by '+' */
  28.  
  29. main(argc,argv) /* Returns # of free bytes on drive N or the default drive,  */
  30. int  argc;    /* or--if drive spec is "M"--returns free RAM memory.  If a  */
  31. char *argv[];    /* numeric spec. is given, FREE will set the errorlevel to 1 */
  32. {        /* if this amount of free space or memory is not available.  */
  33.         /* If arg of + (plus sign) is included, detailed info given. */
  34.         /* For minimum code size, bind with CSTDIO7.S (no floating   */
  35.         /* point is actually used, so this reduces the size of the   */
  36.         /* routines bound with printf()).   Also, bind with a stack  */
  37.         /* size of 400h (bind free -s400). PUBLIC DOMAIN  V. T. Bly  */
  38.  
  39.     int  n, drive = 0;           /*  0 => default (current) drive number */
  40.     char c;
  41.  
  42.     for (n = argc - 1; n > 0; n--) { /** Scan command line arguments **/
  43.     c = *argv[n];
  44.     if (isdigit(c))         /* If argument is numeric, set */
  45.         minval = atol(argv[n]);    /* minimum required memory value */
  46.     else if (c == '+')              /* set verbose if arg is '+' */
  47.         verbose = 1;
  48.     else
  49.         drive = (c & 95) - '@';     /* else, calc. drive number */
  50.     }
  51.     if (drive == 13) {
  52.     /*** CALCULATE FREE RAM MEMORY ***/
  53.           /* Free ram is computed from the value of the PSP segment  */
  54.           /* (which starts at the lowest available memory location)  */
  55.           /* & top of ram value (stored as the 2nd word in the PSP). */
  56.           /* Shift by 4 (* 16) to convert from paragraphs to bytes.  */
  57.     pspseg = _showcs() - 0x10;        /* trace back to PSP segment */
  58.     topram = _peek(2, pspseg) + (_peek(3, pspseg) << 8);/* top ram in PSP */
  59.     free_bytes = ((long)topram - pspseg) << 4;/* actual memory available */
  60.     puts("\nRAM memory: ");
  61.     } else {
  62.     /*** CALCULATE FREE DISK SPACE ***/
  63.     _rdx = drive;
  64.     DOS_FUNC(0x36);         /* get disk free space */
  65.     if (_rax == 0xffff) {
  66.         puts("\n** Invalid Drive **\n");
  67.         exit(2);
  68.     }
  69.     free_bytes = (long)_rbx * _rax * _rcx;
  70.         /* (free = free clusters * sectors/cluster * bytes/sector) */
  71.     n = _rax;   /* save it */
  72.     if (drive == 0) {        /* if default drive, calc drive number */
  73.         DOS_FUNC(0x19);
  74.         drive = (_rax & 0xff) + 1;
  75.     }
  76.     _rax = n;   /* restore it */
  77.     printf("\nDrive %c: ", (char)drive + '@');
  78.     }
  79.     finish(drive);        /* print output data & exit to DOS */
  80.  
  81. }
  82.  
  83.  
  84. finish(drive) /* Finish printing free bytes and exit to DOS, giving an error */
  85. int  drive;   /* if there are insufficient bytes to meet minimum required.   */
  86. {          /* If the verbose flag is set, display additional data */
  87.     long val;
  88.  
  89.     if (verbose) {
  90.     puts("\n");
  91.     if (drive == 13) {
  92.         val = ((long)topram << 4) - 1L;
  93.         printf(" Top of RAM     = %7s [%05lx]\n", lngp(val), val);
  94.         val = (long)pspseg << 4;
  95.         printf(" Next free addr = %7s [%05lx]\n", lngp(val), val);
  96.         printf(" Free bytes     = %7s [%05lx]\n", lngp(free_bytes), free_bytes);
  97.     } else {
  98.         printf(" Sectors/cluster = %10s [%04x]\n", lngp((long)_rax), _rax);
  99.         printf(" Bytes/sector    = %10s [%04x]\n", lngp((long)_rcx), _rcx);
  100.         val = (long)_rax * _rcx;
  101.         printf(" Bytes/cluster   = %10s [%04lx]\n", lngp(val), val);
  102.         val = (long)_rax * _rcx * _rdx;
  103.         printf(" Total clusters  = %10s [%04x]\n", lngp((long)_rdx), _rdx);
  104.         printf(" Free clusters   = %10s [%04x]\n", lngp((long)_rbx), _rbx);
  105.         printf(" Total bytes     = %10s [%05lx]\n", lngp(val), val);
  106.         printf(" Free bytes      = %10s [%05lx]\n", lngp(free_bytes), free_bytes);
  107.  
  108.     }
  109.     } else {
  110.     printf("%s bytes free\n", lngp(free_bytes));
  111.     }
  112.     exit(free_bytes < minval);
  113. }
  114.  
  115.  
  116. lngp(val)   /* Format long integer val for printing with commas */
  117. long val;        /* value to be formatted */
  118. {
  119.     static char fmtn[13];        /* holds formatted number */
  120.     char buff[13];            /* temporary working buffer */
  121.     int  d, i, j, l;
  122.  
  123.     sprintf(buff, "%ld", val);          /* first, format w/o commas */
  124.     l = strlen(buff);
  125.     d = l % 3;
  126.     for (i = 0, j = 0; i < l; i++) {    /* copy into s w/commas inserted */
  127.     fmtn[j + i] = buff[i];
  128.     --d;
  129.     if ((i != (l - 1)) && ((d % 3) == 0)) {
  130.         ++j;
  131.         fmtn[j + i] = ',';
  132.     }
  133.     }
  134.     fmtn[j + i] = '\0';                 /* add terminating 0 */
  135.     return(fmtn);            /* return pointer to fmtn[0] */
  136. }
  137.